package au.com.iglootech.component;

import java.util.Collection;

import org.apache.commons.lang.StringUtils;

import com.vaadin.data.Property;
import com.vaadin.data.Validator;
import com.vaadin.data.Validator.InvalidValueException;
import com.vaadin.data.validator.IntegerValidator;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.Field;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.TextField;

/**
 * 
 * @author zhuhome
 * 
 */
public class IGTTfnField extends CustomComponent implements Field {

	/**
	 * 
	 */
	private static final long serialVersionUID = -5318880852623554041L;
	private final HorizontalLayout mainLayout = new HorizontalLayout();
	private static final int MAX_LEN = 9;
	private static final int FIRST_LEN = 3;
	private static final int SECOND_KEN = 6;

	private TextField firstField;
	private TextField secondField;
	private TextField thirdField;

	private boolean bInvalidCommitted;
	private boolean bWriteThrough;
	private boolean bReadThrough;

	private boolean isRequired;
	private String requiredMessage;

	private Property dataSource = null;

	/**
	 * constructor.
	 */
	public IGTTfnField() {
		super();
		initContent();
		setCompositionRoot(mainLayout);
	}

	/**
	 * init.
	 */
	protected final void initContent() {
		firstField = new TfnUnitField();
		secondField = new TfnUnitField();
		thirdField = new TfnUnitField();
		mainLayout.setSpacing(true);
		mainLayout.addComponent(firstField);
		mainLayout.addComponent(new Label(" - "));
		mainLayout.addComponent(secondField);
		mainLayout.addComponent(new Label(" - "));
		mainLayout.addComponent(thirdField);

	}

	@Override
	public final boolean isInvalidCommitted() {
		// TODO Auto-generated method stub
		return bInvalidCommitted;
	}

	@Override
	public final void setInvalidCommitted(final boolean isCommitted) {
		bInvalidCommitted = isCommitted;
	}

	@Override
	public final void commit() throws SourceException {
		if (isRequired) {
			if (StringUtils.isEmpty((String) firstField.getValue())
					|| StringUtils.isEmpty((String) secondField.getValue())
					|| StringUtils.isEmpty((String) thirdField.getValue())) {
				throw new InvalidValueException("Invalid TFN");
			}
		}
		dataSource.setValue(getValue());
	}

	@Override
	public void discard() throws SourceException {
		// TODO Auto-generated method stub

	}

	@Override
	public final boolean isWriteThrough() {
		return bWriteThrough;
	}

	@Override
	public final void setWriteThrough(final boolean writeThrough)
			throws SourceException {
		bWriteThrough = writeThrough;
	}

	@Override
	public final boolean isReadThrough() {
		return bReadThrough;
	}

	@Override
	public final void setReadThrough(final boolean readThrough)
			throws SourceException {
		bReadThrough = readThrough;
	}

	@Override
	public final boolean isModified() {
		return false;
	}

	@Override
	public void addValidator(final Validator validator) {
		// TODO Auto-generated method stub

	}

	@Override
	public void removeValidator(final Validator validator) {
		// TODO Auto-generated method stub

	}

	@Override
	public final Collection<Validator> getValidators() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public final boolean isValid() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public final void validate() {
		if (this.isRequired) {
			firstField.validate();
			secondField.validate();
			thirdField.validate();
			String result = (String) firstField.getValue()
					+ (String) secondField.getValue()
					+ (String) thirdField.getValue();
			if (result.length() != MAX_LEN) {
				throw new InvalidValueException(
						"TFN must have 9 bit charactors");
			}
		}
	}

	@Override
	public final boolean isInvalidAllowed() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void setInvalidAllowed(final boolean invalidValueAllowed) {
		// TODO Auto-generated method stub

	}

	@Override
	public final Object getValue() {
		// TODO Auto-generated method stub
		return (String) firstField.getValue() + (String) secondField.getValue()
				+ (String) thirdField.getValue();
	}

	@Override
	public final void setValue(final Object newValue) throws ReadOnlyException {
		if (!(newValue instanceof String)) {
			throw new ConversionException();
		}
		String tfn = (String) newValue;
		if (tfn.length() > 0 && tfn.length() != MAX_LEN) {
			throw new ConversionException("TFN must have 9 bit charactors");
		} else if (tfn.length() == MAX_LEN) {
			firstField.setValue(tfn.substring(0, FIRST_LEN));
			secondField.setValue(tfn.substring(FIRST_LEN, SECOND_KEN));
			thirdField.setValue(tfn.substring(SECOND_KEN));
		}
	}

	@Override
	public final Class<?> getType() {
		// TODO Auto-generated method stub
		return IGTTfnField.class;
	}

	@Override
	public void addListener(final ValueChangeListener listener) {
		// TODO Auto-generated method stub

	}

	@Override
	public void removeListener(final ValueChangeListener listener) {
		// TODO Auto-generated method stub

	}

	@Override
	public void valueChange(
			final com.vaadin.data.Property.ValueChangeEvent event) {
		// TODO Auto-generated method stub

	}

	@Override
	public final void setPropertyDataSource(final Property newDataSource) {
		this.dataSource = newDataSource;
		// set value
		if (dataSource.getValue() != null) {
			setValue(dataSource.getValue());
		}

	}

	@Override
	public final Property getPropertyDataSource() {
		return dataSource;
	}

	@Override
	public final int getTabIndex() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public void setTabIndex(final int tabIndex) {
		// TODO Auto-generated method stub

	}

	@Override
	public final boolean isRequired() {
		return isRequired;
	}

	@Override
	public final void setRequired(final boolean required) {
		isRequired = required;
		requestRepaint();
	}

	@Override
	public final void setRequiredError(final String requiredMessage) {
		this.requiredMessage = requiredMessage;
		requestRepaint();
	}

	@Override
	public final String getRequiredError() {
		return requiredMessage;
	}

	@Override
	public final void focus() {
		super.focus();
	}

	@Override
	public final void paintContent(final PaintTarget target)
			throws PaintException {

		// The tab ordering number
		if (getTabIndex() != 0) {
			target.addAttribute("tabindex", getTabIndex());
		}

		// If the field is modified, but not committed, set modified attribute
		if (isModified()) {
			target.addAttribute("modified", true);
		}

		// Adds the required attribute
		if (!isReadOnly() && isRequired()) {
			target.addAttribute("required", true);
		}
		super.paintContent(target);
	}

	/**
	 * 
	 * @author zhuhome
	 * 
	 */
	@SuppressWarnings("serial")
	public class TfnUnitField extends TextField {
		/**
		 * 
		 */
		public TfnUnitField() {
			setMaxLength(FIRST_LEN);

			setWidth("30px");
			addValidator(new IntegerValidator("TFN must be an Integer"));
		}
	}
}
